#include "stdafx.h"
#include "RoomTimerThread.h"
#include "WindowsUtility.h"

namespace RoomFW {

RoomTimerThread::RoomTimerThread(RoomTimer::IdMgr* idMgr) :
	stopEvent_(),
	timer_(idMgr)
{
}

RoomTimerThread::~RoomTimerThread()
{
	SUPER::stop(); // Before closing synch objects.
}

RoomTimer::TimerId RoomTimerThread::setTimer(IActiveObject* handler,
											 RoomMessageSP expirationMessage,
											 const TimeValue& expireIn,
											 const TimeValue& repeatEvery)
{
	return timer_.setTimer(handler, expirationMessage, expireIn, repeatEvery);
}


bool RoomTimerThread::cancelTimer(RoomTimer::TimerId timerId)
{
	return timer_.cancelTimer(timerId);
}

bool RoomTimerThread::initializeObject()
{
	return (stopEvent_.create() && timer_.initialize(MAXIMUM_WAIT_OBJECTS - EventCount));
}

void RoomTimerThread::main()
{
	bool running = true;
	do
	{
		HandleArray handles;
		handles.reserve(timer_.size() + EventCount);
		handles.push_back(stopEvent_);
		timer_.addHandles(handles);
		DWORD ret = ::WaitForMultipleObjectsEx((DWORD)(handles.size()), &(handles.front()), false, INFINITE, false);
		SHOW_LAST_ERROR((WAIT_FAILED != ret), "RoomTimerThread::main", "::WaitForMultipleObjectsEx");
		if ((ret >= (WAIT_OBJECT_0 + EventCount)) && (ret < WAIT_ABANDONED))
		{
			timer_.signal(handles[ret - WAIT_OBJECT_0]);
		}
		else
		{
			running = false;
		}
	} while (running);
}

void RoomTimerThread::signalStop()
{
	stopEvent_.set();
}

const char* RoomTimerThread::getThreadName() const
{
	return "RoomTimerThread";
}


}
